#!/usr/bin/env bash

RUN_TIME=180
BANDWIDTH=25G
PARALLEL=4
LOG_PATH=./
IPERF=./iperf
# CS_LIST_FILE文件格式：
# 每行包含两个空格隔开的IPv4地址，第一个是客户端IP，第二个是服务端IP
CS_LIST_FILE=./client-server-list

# 保存命令行指定的IP: [客户端IP|服务端IP] [服务端IP]
if (($# >= 2)); then
	ASSIGNED_CLIENT_IP=$1
	ASSIGNED_SERVER_IP=$2
else
	ASSIGNED_SERVER_IP=$1
fi

tries=100
while [[ ! -f "${CS_LIST_FILE}" ]] && ((tries-- > 0)); do
	sleep 6
done

CS_IP_ARRAY=()
function init_cs_ip()
{
	#
	# 查找并保存以所有本地IP为客户端IP的所有"客户端IP 服务端IP"
	#
	CS_IP_ARRAY=()
	[[ ! -f "${CS_LIST_FILE}" || ! -s "${CS_LIST_FILE}" ]] && return
	local host_ip=($(hostname -I | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"))
	local c_ip
	local cs_ip
	for c_ip in "${host_ip[@]}"; do
		mapfile -t cs_ip < <(grep -E "^\s*${c_ip}\s+" ${CS_LIST_FILE})
		CS_IP_ARRAY+=("${cs_ip[@]}")
	done
	# 打乱顺序
	mapfile -t CS_IP_ARRAY < <(printf "%s\n" "${CS_IP_ARRAY[@]}" | grep -v '^[[:space:]]*$' | shuf)
	printf "%s\n%s\n" "client -> server: ${#CS_IP_ARRAY[@]}" "${CS_IP_ARRAY[@]}"
}

function set_cs_ip()
{
	#
	# 设置客户端和服务端IP，命令行指定的IP优先
	# 按顺序选择本地IP作为客户端IP，服务端IP跟客户端IP对应
	#
	((cs_idx+=0))
	local cs_cnt=${#CS_IP_ARRAY[@]}
	local cs_ip=($(((${cs_cnt} > 0)) && echo "${CS_IP_ARRAY[$((${cs_idx} % ${cs_cnt}))]}" || echo ""))
	((cs_idx++))
	if ((${#cs_ip[@]} >= 2)); then
		CLIENT_IP=${ASSIGNED_CLIENT_IP:-${cs_ip[0]}}
		SERVER_IP=${ASSIGNED_SERVER_IP:-${cs_ip[1]}}
	elif ((${#cs_ip[@]} == 1)); then
		CLIENT_IP=${ASSIGNED_CLIENT_IP:-${cs_ip[0]}}
		SERVER_IP=${ASSIGNED_SERVER_IP:-${CLIENT_IP}}
	else
		CLIENT_IP=${ASSIGNED_CLIENT_IP:-"0.0.0.0"}
		SERVER_IP=${ASSIGNED_SERVER_IP:-"0.0.0.0"}
	fi
	echo "${CLIENT_IP} -> ${SERVER_IP}"
}

function iperf_tcp_client()
{
	${IPERF} -c ${SERVER_IP} -B ${CLIENT_IP} -b ${BANDWIDTH} -P ${PARALLEL} -t ${RUN_TIME} -i 60
}

function iperf_udp_client()
{
	${IPERF} -u -c ${SERVER_IP} -B ${CLIENT_IP} -b ${BANDWIDTH} -P ${PARALLEL} -t ${RUN_TIME} -i 60
}

sleep 3
init_cs_ip
printf "%s\n%s\n%s\n" "$(date):" "client -> server: ${#CS_IP_ARRAY[@]}" "${CS_IP_ARRAY[@]}" > ${LOG_PATH}/iperf-client.log
printf "%s\n%s\n%s\n" "$(date):" "client -> server: ${#CS_IP_ARRAY[@]}" "${CS_IP_ARRAY[@]}" > ${LOG_PATH}/iperf_tcp_client.log
printf "%s\n%s\n%s\n" "$(date):" "client -> server: ${#CS_IP_ARRAY[@]}" "${CS_IP_ARRAY[@]}" > ${LOG_PATH}/iperf_udp_client.log
while true; do
	set_cs_ip
	sleep 3
	echo "$(date): TCP ${CLIENT_IP} -> ${SERVER_IP}" >> ${LOG_PATH}/iperf-client.log
	echo "$(date): TCP ${CLIENT_IP} -> ${SERVER_IP}" >> ${LOG_PATH}/iperf_tcp_client.log
	iperf_tcp_client >> ${LOG_PATH}/iperf_tcp_client.log 2>&1
	sleep 3
	echo "$(date): UDP ${CLIENT_IP} -> ${SERVER_IP}" >> ${LOG_PATH}/iperf-client.log
	echo "$(date): UDP ${CLIENT_IP} -> ${SERVER_IP}" >> ${LOG_PATH}/iperf_udp_client.log
	iperf_udp_client >> ${LOG_PATH}/iperf_udp_client.log 2>&1
done
